/**
 * Copyright (c) 2010 sonntagsfarben.de
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
package de.sonntagsfarben.display
{
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;

	/**
	 * @author Soenke Kluth <sonntagsfarben.de>
	 * @copyright (c) 2010 Soenke Kluth.
	 */
	[Event(name="open", type="flash.events.Event")]	

	[Event(name="complete", type="flash.events.Event")]	

	[Event(name="init", type="flash.events.Event")]	

	[Event(name="progress", type="flash.events.ProgressEvent")]	

	[Event(name="ioError", type="flash.events.IOErrorEvent")]	

	[Event(name="securityError", type="flash.events.SecurityErrorEvent")]	

	public class BitmapLoader extends CoreBitmap implements ILoader
	{
		private var _loader : Loader;
		private var _url : String;
		private var _loading : Boolean;
		private var _percent : Number;
		private var _properties : Object;

		public function BitmapLoader( url : String = "" , properties : Object = null )
		{
			super();
			this.url = url;
			_properties = properties;
			_initLoader();
		}

		
		private function _initLoader() : void
		{
			_loader = new Loader();
			_loader.contentLoaderInfo.addEventListener(Event.OPEN, onLoadStart, false, 10, true);
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete, false, 10, true);
			_loader.contentLoaderInfo.addEventListener(Event.INIT, onInit, false, 10, true);
			_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress, false, 10, true);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError, false, 10, true);
			_loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError, false, 10, true);
		}

		
		protected function onLoadStart( event : Event ) : void
		{
			_loading = true;
			dispatchEvent(event);
		}

		
		protected function onInit( event : Event ) : void
		{
			dispatchEvent(event);
		}

		
		protected function onComplete( event : Event ) : void
		{
			_loading = false;

			try {
				var bitmap : Bitmap = loader.content as Bitmap;

				if ( bitmapData )
					bitmapData.dispose();
				this.bitmapData = bitmap.bitmapData.clone();
				smoothing = true;
			}
			catch ( any : * ) {
				trace(this + " loaded data seems to be no bitmap :: ");
			}


			if ( _properties )
			{
				for ( var i : String in _properties )
				{
					try {
						this[ i ] = _properties[ i ];
					}
					catch ( any : * ) {
						trace(this + " WARNING: property could not be set: " + i + " with value: " + _properties[ i ]);
					}
				}
			}


			//reset();
			dispatchEvent(event);
		}

		
		protected function onProgress( event : ProgressEvent ) : void
		{
			_percent = event.bytesLoaded / event.bytesTotal;

			if ( isNaN(_percent) || !isFinite(_percent))
				_percent = 0;
			dispatchEvent(event);
		}

		
		protected function onError( event : ErrorEvent ) : void
		{
			trace("IOERROR " + event.text);
			//dispatchEvent(event);
		}

		
		public function destroy() : void
		{
			close();

			if ( !_loader )
				return;
			_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onComplete);
			_loader.contentLoaderInfo.removeEventListener(Event.INIT, onInit);
			_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
			_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onError);
			_loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
			_loader = null;
		}

		
		public function reset() : void
		{
			_initLoader();
		}

		
		public function load(...args) : void
		{
			if ( _url == "" )
			{
				throw new Error(this + " url is not set. data will not be loaded");
			}
			else
				_loader.load(new URLRequest(_url));
		}

		
		public function get content() : Bitmap
		{
			if ( loader )
				return loader.content as Bitmap;
			return null;
		}

		
		public function get loader() : Loader
		{
			return _loader;
		}

		
		public function get percent() : Number
		{
			return _percent;
		}

		
		public function close() : void
		{
			if ( !_loader )
				return;

			try {
				_loader.close();
			}
			catch ( any : * ) {
				//trace(this + " exception, information=Error: Error #2029: Dieses URLStream-Objekt hat keinen geöffneten Stream.");
			}
			_loading = false;
		}

		
		public function get loading() : Boolean
		{
			return _loading;
		}

		
		public function get url() : String
		{
			return _url;
		}

		
		public function set url( url : String ) : void
		{
			_url = url;
		}
	}
}
